#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>                         // 提供close()函数 
#include "io_lib.h" 
int set_fl(int fd,int flag)
{
	flag |= fcntl(fd,F_GETFL);
	if(fcntl(fd,F_SETFL,flag) < 0)
	{
		return 0;
	}
	return 1;
}
int clear_fl(int fd)
{
	int flag = fcntl(fd,F_GETFL);
	flag &= ~flag;
	if(fcntl(fd,F_SETFL,flag) < 0)
	{
		return 0;
	}
	return 1;
}
void cat(int argc,char* argv[])
{
	int flag_arr[4] = {-1,-1,-1,-1},i = 1,stdin_temp = -1,stdout_temp = -1,file_temp = -1,argc_temp = argc;
	if(argc > 2)
	{
		for(;i < (argc_temp - 1);i++)
		{
			// 修改输入重定向
			if(strcmp("+",argv[i]) == 0)
			{
				flag_arr[0] = i++;
				flag_arr[1] = i;
				// 备份下标准输入，函数执行完毕后恢复
				stdin_temp = dup(STDIN_FILENO);
				file_temp = open(argv[i],O_RDONLY);
				if(file_temp == -1)
				{
					perror("open input file error");
				}
				dup2(file_temp,STDIN_FILENO);
				argc -= 2;
			}
			// 修改输出重定向
			if(strcmp("-",argv[i]) == 0)
			{
				flag_arr[2] = i++;
				flag_arr[3] = i;
				// 备份下标准输入，函数执行完毕后恢复
				stdout_temp = dup(STDOUT_FILENO);
				file_temp = open(argv[i],O_CREAT | O_WRONLY | O_TRUNC,0777);
				if(file_temp == -1)
				{
					perror("create or open output file error");
				}
				dup2(file_temp,STDOUT_FILENO);
				argc -= 2;
			}
		}
	}
	// 同时输入了输入和输出
	if(flag_arr[0] != -1 && flag_arr[2] != -1)
	{
		argc = flag_arr[1] + 1;
		flag_arr[1] = -1;
	}
	int in = STDIN_FILENO;
	int out = STDOUT_FILENO;
	if(argc == 1)
	{
		cp_by_file_no(in,out);
	}
	else
	{
		for(i = 1;i < argc;i++)
		{
			if(in_array(i,flag_arr,4) == 1)
			{
				continue;
			}
			in = open(argv[i],O_RDONLY);
			if(in == -1)
			{
				perror("open file error:");
			}
			cp_by_file_no(in,out);
		}
	}
	// 恢复标准输入输出
	if(flag_arr[0] != -1)
	{
		dup2(stdin_temp,STDIN_FILENO);
	}
	if(flag_arr[2] != -1)
	{
		dup2(stdout_temp,STDOUT_FILENO);
	}
}
int file_hole(char* file_path)
{
	int f = open(file_path,O_CREAT | O_WRONLY | O_TRUNC,0777);
	if(f == -1)
	{
		perror("open or create file:");
		return 0;
	}
	char buffer[] = "abcdef";
	if(sizeof(buffer) != write(f,buffer,sizeof(buffer)))
	{
		perror("write file:");
		return 0;
	}
	lseek(f,8,SEEK_END);
	if(sizeof(buffer) != write(f,buffer,sizeof(buffer)))
	{
		perror("write file:");
		return 0;
	}
	close(f);
	return 1;
}
int file_size(char* file_path)
{
	int f = open(file_path,O_RDONLY);
	return lseek(f,0,SEEK_END);
}
int cp(char* source,char* destination)
{
	int s = open(source,O_RDONLY);
	int d = open(destination,O_CREAT | O_WRONLY | O_TRUNC,0777);
	if(s == -1 || d == -1)
	{
		fprintf(stderr,"open file error %s \n",strerror(errno));
		return 0;
	}
	int buffer_length = 888,read_flag = 0;
	char buffer[buffer_length];
	while((read_flag = read(s,buffer,buffer_length)) != 0)
	{
		// 只写入读取到的数据
		if(read_flag > write(d,buffer,read_flag))
		{
			fprintf(stderr,"write file error %s \n",strerror(errno));
			return 0;
		}
		memset(buffer,'\0',buffer_length);
	}
	close(s);
	close(d);
	return 1;
}
int cp_by_file_no(int s,int d)
{
	// int s = open(source,O_RDONLY);
	// int d = open(destination,O_CREAT | O_WRONLY | O_TRUNC,0777);
	if(s == -1 || d == -1)
	{
		fprintf(stderr,"open file error %s \n",strerror(errno));
		return 0;
	}
	int buffer_length = 888,read_flag = 0;
	char buffer[buffer_length];
	while((read_flag = read(s,buffer,buffer_length)) != 0)
	{
		// 只写入读取到的数据
		if(read_flag > write(d,buffer,read_flag))
		{
			fprintf(stderr,"write file error %s \n",strerror(errno));
			return 0;
		}
		memset(buffer,'\0',buffer_length);
	}
	close(s);
	close(d);
	return 1;
}
int in_array(int v,int* arr,int length)
{
	for(int i = 0;i < length;i++)
	{
		if(arr[i] == v)
		{
			return 1;
		}
	}
	return 0;
}
